<template>
  <div class="pull-select">
    <el-button type="primary" @click="clickHandle">{{ text }}<i :class="{ 'el-icon-arrow-down': !visible, 'el-icon-arrow-up': visible }" style="padding-left:2px" /></el-button>
    <div v-show="visible" class="arrow" />
    <transition name="el-zoom-in-top">
      <div v-if="visible" ref="popper" class="list">
        <el-scrollbar
          v-show="list.length > 0"
          ref="scrollbar"
          tag="div"
          wrap-class="el-select-dropdown__wrap"
          view-class="el-select-dropdown__list"
          :class="{ 'is-empty': list.length === 0 }"
        >
          <ul class="ul-list">
            <li v-for="(l, i) in list" :key="i" class="list-item" @click.stop="liClickHandle(l)">
              <span :class="{selected: l.selected}">{{ l[labelName] }}</span>
              <i v-show="l.selected" class="el-icon-check icon" />
            </li>
            <li v-if="!dictTypeCode&&method.toLowerCase()==='post'&&!finished" class="list-item" style="justify-content:center;" @click.top="moreClickHandle">
              <span>加载更多</span>
            </li>
          </ul>
        </el-scrollbar>
        <template v-if="emptyText && list.length === 0">
          <p class="el-select-dropdown__empty">
            {{ emptyText }}
          </p>
        </template>
        <div v-show="list.length>0" class="btn">
          <el-button type="primary" @click="cancleHandle">取消</el-button>
          <el-button type="primary" @click="confirmHandle">确定</el-button>
        </div>
      </div>
    </transition>
  </div>
</template>
<script>
import { SLMDict } from '@/api/dataDict'
import request from '@/utils/request'
import { otherFiltersItem } from '@/utils'
export default {
  name: 'CPullSelect',
  components: {},
  props: {
    text: {
      type: String,
      default: '新增'
    },
    labelName: {
      type: String,
      default: 'dictName'
    },
    multiple: {
      type: Boolean,
      default: false
    },
    emptyText: {
      type: String,
      default: '暂无数据'
    },
    dictTypeCode: {
      type: String,
      default: ''
    },
    closeClear: {
      type: Boolean,
      default: true
    },
    url: {
      type: String,
      default: ''
    },
    method: {
      type: String,
      default: 'POST'
    },
    paramsRaw: {
      type: Object,
      default: undefined
    },
    filtersRaw: {
      type: Array,
      default: undefined
    },
    sort: {
      type: String,
      default: undefined
    },
    order: {
      type: String,
      default: undefined
    }
  },
  data() {
    return {
      list: [],
      visible: false,
      page: 1,
      pageSize: 20,
      finished: false
    }
  },
  watch: {
    // visible(v) {
    //   if (!v) {
    //     this.$emit('change', this.list.filter(e => e.selected))
    //     if (this.closeClear) {
    //       this.clearAllSelected()
    //     }
    //   }
    // }
  },
  created() {
    this.getList()
  },
  methods: {
    getDict() {
      SLMDict(this.dictTypeCode).then((res) => {
        this.list = res.data
      })
    },
    getData() {
      const cfg = {
        url: this.url,
        method: this.method
      }
      if (this.method.toLowerCase() === 'post') {
        const data = new FormData()
        if (this.paramsRaw) {
          data.append('paramsRaw', JSON.stringify(this.paramsRaw))
        }
        if (this.filtersRaw) {
          data.append('filtersRaw', JSON.stringify(this.filtersRaw.map(e => {
            return otherFiltersItem(e.key, e.value, e.operator || 'like')
          })))
        }
        data.append('page', this.page)
        data.append('rows', this.pageSize)
        if (this.sort) {
          data.append('sort', this.sort)
        }
        if (this.order) {
          data.append('sort', this.order)
        }
        cfg.data = data
      }
      request(cfg).then(res => {
        if (this.method.toLowerCase() === 'post') {
          this.list.push(...res.data.records)
          this.page += 1
          if (this.list.length >= res.data.total) {
            this.finished = true
          }
        } else {
          this.list = res.data
        }
      })
    },
    getList() {
      if (this.dictTypeCode) {
        this.getDict()
      } else {
        this.getData()
      }
    },
    clickHandle() {
      if (this.visible) {
        this.clearAllSelected()
      }
      this.visible = !this.visible
    },
    liClickHandle(value) {
      const selected = value.selected
      if (!this.multiple) {
        this.clearAllSelected()
      }
      this.$set(value, 'selected', !selected)
    },
    clearAllSelected() {
      this.list.forEach(e => {
        this.$set(e, 'selected', false)
      })
    },
    moreClickHandle() {
      this.getList()
    },
    cancleHandle() {
      this.visible = false
      this.clearAllSelected()
    },
    confirmHandle() {
      this.$emit('change', this.list.filter(e => e.selected))
      this.visible = false
      if (this.closeClear) {
        this.clearAllSelected()
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.pull-select{
  display: inline-block;
  position: relative;
  .arrow{
    position: absolute;
      top: 25px;
      left: 15px;
      margin-left: 0px;
      border: 8px solid transparent;
      border-bottom-color: #fff;
      z-index: 99999;
    }
  .list{
    display: inline-block;
    position: absolute;
    z-index: 9999;
    top: 40px;
    left: 0;
    background-color: #fff;
    border-radius: 4px;
    overflow: hidden;
    min-width: 240px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0 , 0.1);
    border: 1px solid #e4e7ed;
  }
  .ul-list{
    list-style: none;
    padding: 0;
    margin: 0;
    background-color: #fff;
    .list-item{
      display: flex;
      justify-content: space-between;
      align-items: center;
      cursor: pointer;
      min-height: 34px;
      padding: 5px 15px;
      .icon{
        color: #37ad85 !important;
      }
      &:hover{
        background-color: #f5f7fa;
      }
    }
    .selected {
      color: #37ad85 !important;
    }
  }
  .btn{
    padding: 5px 15px;
    display: flex;
    justify-content: flex-end;
  }
}
</style>
